/**
 * 
 */
package me.chnxan.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.springframework.context.i18n.LocaleContextHolder;

/**
 * @author David Yang
 *
 */
public class DateUtil {
	private static Log log = LogFactory.getLog(DateUtil.class);
    
    private static String minTimePattern = "HH:mm";
    private static String secTimePattern = "HH:mm:ss";
    private static String timePattern = "HH:mm:ss.S";
    
    private static String datePattern = "MM/dd/yyyy";
    private static String cnDatePattern = "yyyy-MM-dd";

    //~ Methods ================================================================

    /**
     * Return default datePattern (MM/dd/yyyy)
     * @return a string representing the date pattern on the UI
     */
    public static String getDatePattern() {
        Locale locale = LocaleContextHolder.getLocale();
        if (locale.toString().equals("zh_CN")) {
        	datePattern = cnDatePattern;
        } else {
        	datePattern = cnDatePattern;
        }
        
        return datePattern;
    }
    public static String getDateTimePattern() {
        return DateUtil.getDatePattern() + " HH:mm:ss.S";
    }
    public static String getDateTimeShortPattern() {
        return DateUtil.getDatePattern() + " HH:mm:ss";
    }
    /**
     * This method returns the current date time in the format:
     * MM/dd/yyyy HH:MM a
     *
     * @param theTime the current time
     * @return the current date/time
     */
    public static String getTime(Date theTime) {
        return convert(timePattern, theTime);
    }
    public static String getSecTime(Date theTime) {
        return convert(secTimePattern, theTime);
    }
    public static String getMinTime(Date theTime) {
        return convert(minTimePattern, theTime);
    }
    public static String getDateTime(Date date) {
		return convert(getDateTimeShortPattern(), date);
	}
    /**
     * This method generates a string representation of a date's date/time
     * in the format you specify on input
     *
     * @param mask the date pattern the string is in
     * @param date a date object
     * @return a formatted string representation of the date
     * 
     * @see java.text.SimpleDateFormat
     */
    public static final String convert(String mask, Date date) {
        SimpleDateFormat df = null;
        String returnValue = "";

        if (date == null) {
            log.error("aDate is null!");
        } else {
            df = new SimpleDateFormat(mask);
            returnValue = df.format(date);
        }

        return (returnValue);
    }
    /**
     * This method generates a string representation of a date/time
     * in the format you specify on input
     *
     * @param mask the date pattern the string is in
     * @param strDate a string representation of a date
     * @return a converted Date object
     * @see java.text.SimpleDateFormat
     * @throws ParseException
     */
    public static final Date convert(String mask, String strDate) {
        SimpleDateFormat df = null;
        Date date = null;
        df = new SimpleDateFormat(mask);
        
        if (log.isDebugEnabled()) {
            log.debug("converting '" + strDate + "' to date with mask '" + mask + "'");
        }

        try {
            date = df.parse(strDate);
        } catch (ParseException pe) {
            log.error("ParseException: " + pe);
            //throw new ParseException(pe.getMessage(), pe.getErrorOffset());
        }

        return date;
    }
    /**
     * convert date to string with default date format
     * @param date
     * @return
     */
	public static String convert(Date date) {
		return convert(getDatePattern(), date);
	}
	/**
     * convert String to date with default date format
     * @param date
     * @return
     */
	public static Date convert(String strDate) {
		return convert(getDatePattern(), strDate);
	}
	
	public static String getNow(){
    	return DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
    }
    
    public static String format(Date date, String pattern) {
        DateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }
    
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
	/**
     * Get date by interval days and system date
     * @param intervalDays
     * @return
     */
    public static Date getDate(int intervalDays) {
    	Date sysDate = new Date();
    	DateTime dateTime = new DateTime(sysDate);
		DateTime date = dateTime.plusDays(intervalDays);
		return date.toDate();
	}
	 /**
     * 
     * @param startDate
     * @param endDate
     * @param timeType Time Type eg: S - Second, M - Minute, H - Hour, D - Day
     * @return
     */
    public static long getIntervalTime(String startDate, String endDate, String timeType) {
    	if (startDate.indexOf(":") == -1) startDate = startDate.trim() + " " + "00:00:00";
    	if (endDate.indexOf(":") == -1) endDate = endDate.trim() + " " + "00:00:00";
    	
        Date start = convert(getDatePattern() + " " + secTimePattern, startDate);
        Date end = convert(getDatePattern() + " " + secTimePattern, endDate);
        return getIntervalTime(start, end, timeType);
    }
	/**
	 * 
	 * @param startDate
	 * @param endDate
	 * @param timeType Time Type eg: S - Second, M - Minute, H - Hour, D - Day
	 * @return
	 */
    public static long getIntervalTime(Date startDate, Date endDate, String timeType) {
    	if (timeType.equals("S")){
    		return getIntervalTime(startDate, endDate)/1000;
    	} else if ( timeType.equals("H") ){
    		long times = getIntervalTime(startDate, endDate);
    		return times/1000/60/60;
    	} else if ( timeType.equals("D") ){
    		long times = getIntervalTime(startDate, endDate);
    		return times/1000/60/60/24;
    	}
    	//Default return Minute
 		long times = getIntervalTime(startDate, endDate);
 		return times/1000/60;
    }
    
    /**
	 * millisecond level
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static long getIntervalTime(Date startDate, Date endDate) {
		long intervalTime = endDate.getTime() - startDate.getTime();
		return intervalTime;
	}
	
	public static Map<String,Date> getIntervalTime(Date timeOfPeriod,int inCutDay){
		Map<String,Date> objMap = null;
		if( timeOfPeriod != null ){
			DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			objMap = new HashMap<String,Date>();
			
			String strTimeOfPeriod = sdf.format(timeOfPeriod);
			int inYear = Integer.parseInt(strTimeOfPeriod.substring(0, 4));
			int inMon = Integer.parseInt(strTimeOfPeriod.substring(5, 7));
			int inYearBegin = inYear;
			int inMonBegin = inMon;
			if( inMon <= 1 ){
				inYearBegin = inYear-1;
				inMonBegin = 12;
			}else	inMonBegin = inMon-1;
			
			try {
				Date objDateEffect = sdf.parse(""+inYearBegin+"-"+inMonBegin+"-"+inCutDay);
				
				Calendar calOfExpire = Calendar.getInstance(); 
				calOfExpire.set(Calendar.YEAR, inYear);
				calOfExpire.set(Calendar.MONTH, inMon-1);
				calOfExpire.set(Calendar.DAY_OF_MONTH, inCutDay);
				calOfExpire.set(Calendar.HOUR_OF_DAY, 0);
				calOfExpire.set(Calendar.MINUTE, 0);
				calOfExpire.set(Calendar.SECOND, 0);
				calOfExpire.add(Calendar.DAY_OF_MONTH, -1); 
				Date objDateExpire = calOfExpire.getTime();
				
				objMap.put("Effect", objDateEffect);
				objMap.put("Expire", objDateExpire);
			}catch (ParseException pe) {
	            log.error("ParseException: " + pe);
	        }
		}
		return objMap;
	}
	
	public static Map<String,Date> getIntervalTime(String strType,Date timeOfPeriod,int inCutDay){
		Map<String,Date> objMap = null;
		if( timeOfPeriod != null ){
			objMap = getIntervalTime(timeOfPeriod,inCutDay);
			
			if( strType.toLowerCase().equals("f") ){
				
			}else if( strType.toLowerCase().equals("b") ){
				Calendar objEffectCal = Calendar.getInstance();
				objEffectCal.setTime(objMap.get("Effect"));
				objEffectCal.add(Calendar.MONTH, 1);
				Date objEffectDate = objEffectCal.getTime();
				
				Calendar objExpireCal = Calendar.getInstance();
				objExpireCal.setTime(objMap.get("Expire"));
				objExpireCal.add(Calendar.MONTH, 1);
				Date objExpireDate = objEffectCal.getTime();
				
				objMap.put("Effect", objEffectDate);
				objMap.put("Expire", objExpireDate);
			}
		}
		return objMap;
	}
	
	/**
	 * 获取月份
	 */
	public static String getMonth(Date date) {
		DateTime dateTime = new DateTime(date);
		int month = dateTime.getMonthOfYear();
		String strMonth = "";
		if (month < 10)  strMonth = "0" + month;
		else strMonth = "" + month;
		return strMonth;
	}
	
	/**
	 * 获取日
	 */
	public static String getDay(Date date) {
		DateTime dateTime = new DateTime(date);
		int day = dateTime.getDayOfMonth();
		String strDay = "";
		if (day < 10)  strDay = "0" + day;
		else strDay = "" + day;
		return strDay;
	}
	
	/**
	 * 获取星期
	 */
	public static String getWeek(Date date) {
		DateTime dateTime = new DateTime(date);
		int week = dateTime.getDayOfWeek();
		String strWeek = "";
		if (week < 10)  strWeek = "0" + week;
		else strWeek = "" + week;
		return strWeek;
	}
	
	public static void main(String[] args) {
//		Date date = new Date();
//		String strDate = DateUtil.convert(date);
//		System.out.println(strDate);
//		//test getTime
//		System.out.println("=================test getTime");
//		String time = DateUtil.getTime(date);
//		System.out.println(time);
//		String secTime = DateUtil.getSecTime(date);
//		System.out.println(secTime);
//		String minTime = DateUtil.getMinTime(date);
//		System.out.println(minTime);
//		//test getIntervalTime
//		System.out.println("=================test getIntervalTime");
//		long intervalTime = 0;
//		intervalTime = DateUtil.getIntervalTime("2007-11-07 07:20:30", "2007-11-08 08:00:30", "H");
//		System.out.println(intervalTime);
//		intervalTime = DateUtil.getIntervalTime("2007-11-07", "2007-11-08", "D");
//		System.out.println(intervalTime);
//		//test getDate By interval days
//		System.out.println("=================test getDate by interval days");
//		Date getDate = DateUtil.getDate(9);
//		System.out.println(getDate);
		
		String p_periodTime = DateUtil.convert("yyyy-MM", DateUtil.getDate(0));
		Date dd = DateUtil.convert(p_periodTime + "-01");
		System.out.println(p_periodTime);
		System.out.println(dd);
	}
}
